-
Notifications
You must be signed in to change notification settings - Fork 15.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add CodedInputReader and CodedOutputWriter #5888
Add CodedInputReader and CodedOutputWriter #5888
Conversation
Thanks for your pull request. It looks like this may be your first contribution to a Google open source project (if not, look below for help). Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA). 📝 Please visit https://cla.developers.google.com/ to sign. Once you've signed (or fixed any issues), please reply here (e.g. What to do if you already signed the CLAIndividual signers
Corporate signers
ℹ️ Googlers: Go here for more info. |
A prerequisite PR #5835 has been merged, rebase/merge the current master? |
fc53476
to
e09705a
Compare
I've rebased on master and addressed most PR feedback. This PR isn't finished, but before figuring out every issue that needs to be solved I'd like some feedback from the protocol buffers team. Is this PR on the right track? What do you want to see before the PR can be merged? |
CLAs look good, thanks! ℹ️ Googlers: Go here for more info. |
c4855bc
to
d963fd9
Compare
@jtattermusch Tests now pass.
Take a look 🙏 |
@@ -86,7 +86,7 @@ internal CodedInputReader(ReadOnlySequence<byte> input, int recursionLimit) | |||
this.lastTag = 0; | |||
this.recursionDepth = 0; | |||
this.recursionLimit = recursionLimit; | |||
this.currentLimit = long.MaxValue; | |||
this.currentLimit = (int)this.reader.Length; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not slice the input upfront?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Slice what up front?
Setting the current limit here lets us use this value as "all the remaining content". It avoids an additional check to long.MaxValue when testing the current limit.
Parsing benchmarks are the same, maybe even slightly faster. Perf gain might be from the Int64 -> Int32 length/limit change.
|
@JamesNK some C# test are failing on CI as well as locally. Please doublecheck |
Fixed by removing a ReachedLimit check at the end of ReadTag. I'm not sure what its purpose is. No unit tests use it. |
FTR, these are the performance results I got at commit bdf9f1a. BenchmarkDotNet=v0.12.0, OS=debian rodete
BenchmarkDotNet=v0.12.0, OS=debian rodete
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, I think I'm done with reviewing this mega PR, I think now things are in a good enough shape for this to get merged.
Thanks for bearing with me and thanks for addressing all the comments.
LGTM.
The next step is for someone from the protobuf team to review the overall design and the high-level technical approach (let's consider this PR approved from the C# perspective).
@haberman this is now ready for the final review. The overall design is documented here:
#6874
This has been superseded by #7351 (we still need to add support for serialization). |
What’s the API usage |
var reply = HelloReply.Parser.ParseFrom(data); Data is a |
Basically the entry point is |
Ref or in? |
Feel free to review the PR and add comments if you have any improvements #7351 |
Yes. |
This is very WIP/rough. I had to create a new
ISpanMessage<T>
interface, and some areas do not have full support for it yet (they are throwing NotSupportException right now).Nothing has been done on the code gen side. The way the reader and writer are used compared to the streams is almost identitical so code gen changes should be minimal.
Perf numbers:
WriteToByteArray and ParseFromByteArray both allocate the byte array. This matches how serialization from gRPC works today.
WriteToBufferWriter writes to an
IBufferWriter<byte>
and doesn't allocate at all. For a small message CodedOutputWriter is slower than CodedOutputStream. It is faster for medium/large messages. Still some tuning to be done.ParseFromReadOnlySequence reads from a sequence. Its allocations are related to creating the message and whatever strings exist on the message. Using CodedInputReader is consistently faster than CodedInputStream.
@jskeet @davidfowl @JunTaoLuo @jtattermusch